<cfcomponent output="false">

  <!--- setters for dependencies --->

  <cffunction name="setAuthenticationService" returntype="void" access="public" output="false" hint="Dependency: security service">
    <cfargument name="AuthenticationService" type="any" _type="actionpacks.auth.service.AuthenticationService" required="true"/>
    <cfset variables.m_AuthenticationService = arguments.AuthenticationService/>
  </cffunction>

  <cffunction name="getAuthenticationService" returntype="any" _returntype="actionpacks.auth.service.AuthenticationService" access="public" output="false" hint="Dependency: security service">
    <cfreturn variables.m_AuthenticationService />
  </cffunction>

	<cffunction name="setProjectService" returntype="void" access="public" output="false" hint="coldspring:: Project Service">
		<cfargument name="projectService" required="true"/>
		<cfset variables.projectService = arguments.projectService />
	</cffunction>

	<cffunction name="getProjectService" returntype="any" access="private" output="false" hint="internal: Project Service">
		<cfreturn variables.projectService />
	</cffunction>

	<cffunction name="setAttributeService" returntype="void" access="public" output="false" hint="coldspring:: Attribute Service">
		<cfargument name="attributeService" required="true"/>
		<cfset variables.attributeService = arguments.attributeService />
	</cffunction>

	<cffunction name="getAttributeService" returntype="any" access="private" output="false" hint="internal: Attribute Service">
		<cfreturn variables.attributeService />
	</cffunction>

	<cffunction name="setG11nService" returntype="void" access="public" output="false" hint="coldspring:: Project Service">
		<cfargument name="G11nService" required="true"/>
		<cfset variables.G11nService = arguments.G11nService />
	</cffunction>

	<cffunction name="getG11nService" returntype="any" access="private" output="false" hint="internal: Project Service">
		<cfreturn variables.G11nService />
	</cffunction>

	<cffunction name="setORMService" access="public" returntype="any" output="false" roles="" hint="">
		<cfargument name="ormService" required="true"/>
		<cfset variables._ORMService = arguments.ormService />
	</cffunction>
	<cffunction name="getORMService" access="public" returntype="any" output="false" roles="" hint="">
		<cfreturn variables._ORMService/>
	</cffunction>

	<cffunction name="setTicketService" access="public" returntype="any" output="false" roles="" hint="">
		<cfargument name="ticketService" required="true"/>
		<cfset variables._TicketService = arguments.ticketService/>
	</cffunction>	
	<cffunction name="getTicketService" access="public" returntype="any" output="false" roles="" hint="">
		<cfreturn variables._TicketService/>
	</cffunction>

 	<cffunction name="init" returntype="any" output="false" hint="Constructor">
		<cfargument name="xmlrpc" default=""/>
		<cfset variables._xmlrpc = arguments.xmlrpc />
		<cfreturn this />
	</cffunction>

	<cffunction name="GetEpochTime" access="private" returntype="any" hint="gets project">
		<cfscript>
			var datetime = 0;
			if (ArrayLen(Arguments) is 0) {
				datetime = Now();		
			}
			else {
				if (Arguments[1] gt "" AND IsDate(Arguments[1])) {
					datetime = Arguments[1];
				} else {
//					return NULL;
					return 0;
				}
			}
			return DateDiff("s", "January 1 1970 00:00", datetime);
		</cfscript>
	</cffunction>

	<cffunction name="dumpVar" output="true">
	  <cfargument name="daVar" required="true">
	  <cfargument name="abort" default="true">
	  <cfdump var="#arguments.daVar#" />
	  <cfif arguments.abort>
		  <cfabort />
		</cfif>
	</cffunction>
	
	<cffunction name="setProjectConfigDefaults" access="public" returntype="any" output="false" roles="" hint="">
		<cfargument name="project" type="numeric" required="true">
		<cfset var projectID = arguments.project>
		<cfset var defaultsSQL = "">
		<cfset var sqlQry = "">
		<cfsavecontent variable="defaultsSQL">
			<cfoutput>
			DELETE FROM `projectcomponents` WHERE projectId = '#projectId#';
			DELETE FROM `projectmilestones` WHERE projectId = '#projectId#';
			DELETE FROM `projectpriorities` WHERE projectId = '#projectId#';
			DELETE FROM `projectticketactions` WHERE projectId = '#projectId#';
			DELETE FROM `projectticketresolutions` WHERE projectId = '#projectId#';
			DELETE FROM `projectticketseverities` WHERE projectId = '#projectId#';
			DELETE FROM `projectticketstatuses` WHERE projectId = '#projectId#';
			DELETE FROM `projecttickettypes` WHERE projectId = '#projectId#';
			DELETE FROM `projectversions` WHERE projectId = '#projectId#';

			INSERT INTO `projectcomponents` (`componentId`, `projectId`, `componentName`, `componentDescription`, `createUserID`) VALUES ('0', '#projectId#', 'Component 1', 'Component 1', '3');
			INSERT INTO `projectcomponents` (`componentId`, `projectId`, `componentName`, `componentDescription`, `createUserID`) VALUES ('0', '#projectId#', 'Component 2', 'Component 2', '5');
			INSERT INTO `projectmilestones` (`milestoneId`, `projectId`, `milestoneName`, `milestoneDescription`, `milestoneDueDate`, `milestoneCompleted`, `createUserId`, `createDate`, `modifiedDate`)	VALUES ('0', '#projectId#', 'milestone one', 'some desc for milestone', null, '0', 1, now(), now());
			INSERT INTO `projectmilestones` (`milestoneId`, `projectId`, `milestoneName`, `milestoneDescription`, `milestoneDueDate`, `milestoneCompleted`, `createUserId`, `createDate`, `modifiedDate`) VALUES ('0', '#projectId#', 'milestone two', 'more descriptive milestone stuff', null, '0', 1, now(), now());
			INSERT INTO `projectpriorities` (`priorityId`, `projectId`, `priorityName`, `priorityDescription`, `createUserId`, `createDate`, `modifiedUserId`, `modifiedDate`) VALUES ('0', '#projectId#', 'highest', null, 1, now(), 1, now());
			INSERT INTO `projectpriorities` (`priorityId`, `projectId`, `priorityName`, `priorityDescription`, `createUserId`, `createDate`, `modifiedUserId`, `modifiedDate`) VALUES ('0', '#projectId#', 'high', null, 1, now(), 1, now());
			INSERT INTO `projectpriorities` (`priorityId`, `projectId`, `priorityName`, `priorityDescription`, `createUserId`, `createDate`, `modifiedUserId`, `modifiedDate`) VALUES ('0', '#projectId#', 'normal', null, 1, now(), 1, now());
			INSERT INTO `projectpriorities` (`priorityId`, `projectId`, `priorityName`, `priorityDescription`, `createUserId`, `createDate`, `modifiedUserId`, `modifiedDate`) VALUES ('0', '#projectId#', 'low', null, 1, now(), 1, now());
			INSERT INTO `projectpriorities` (`priorityId`, `projectId`, `priorityName`, `priorityDescription`, `createUserId`, `createDate`, `modifiedUserId`, `modifiedDate`) VALUES ('0', '#projectId#', 'lowest', null, 1, now(), 1, now());
			INSERT INTO `projectticketactions` (`actionId`, `projectId`, `actionName`, `actionDescription`, `createUserId`, `createDate`, `modifiedUserId`, `modifiedDate`) VALUES ('0', '#projectId#', 'leave', null, 1, now(), 1, now());
			INSERT INTO `projectticketactions` (`actionId`, `projectId`, `actionName`, `actionDescription`, `createUserId`, `createDate`, `modifiedUserId`, `modifiedDate`) VALUES ('0', '#projectId#', 'resolve', null, 1, now(), 1, now());
			INSERT INTO `projectticketactions` (`actionId`, `projectId`, `actionName`, `actionDescription`, `createUserId`, `createDate`, `modifiedUserId`, `modifiedDate`) VALUES ('0', '#projectId#', 'reassign', null, 1, now(), 1, now());
			INSERT INTO `projectticketactions` (`actionId`, `projectId`, `actionName`, `actionDescription`, `createUserId`, `createDate`, `modifiedUserId`, `modifiedDate`) VALUES ('0', '#projectId#', 'accept', null, 1, now(), 1, now());
			INSERT INTO `projectticketresolutions` (`resolutionId`, `projectId`, `resolutionName`, `resolutionDescription`, `createUserId`, `createDate`, `modifiedUserId`, `modifiedDate`) VALUES ('0', '#projectId#', 'fixed', null, 1, now(), 1, now());
			INSERT INTO `projectticketresolutions` (`resolutionId`, `projectId`, `resolutionName`, `resolutionDescription`, `createUserId`, `createDate`, `modifiedUserId`, `modifiedDate`) VALUES ('0', '#projectId#', 'invalid', null, 1, now(), 1, now());
			INSERT INTO `projectticketresolutions` (`resolutionId`, `projectId`, `resolutionName`, `resolutionDescription`, `createUserId`, `createDate`, `modifiedUserId`, `modifiedDate`) VALUES ('0', '#projectId#', 'wontfix', null, 1, now(), 1, now());
			INSERT INTO `projectticketresolutions` (`resolutionId`, `projectId`, `resolutionName`, `resolutionDescription`, `createUserId`, `createDate`, `modifiedUserId`, `modifiedDate`) VALUES ('0', '#projectId#', 'duplicate', null, 1, now(), 1, now());
			INSERT INTO `projectticketresolutions` (`resolutionId`, `projectId`, `resolutionName`, `resolutionDescription`, `createUserId`, `createDate`, `modifiedUserId`, `modifiedDate`) VALUES ('0', '#projectId#', 'worksforme', null, 1, now(), 1, now());
			INSERT INTO `projectticketseverities` (`severityId`, `projectId`, `severityName`, `severityDescription`, `createUserId`, `createDate`, `modifiedUserId`, `modifiedDate`) VALUES ('0', '#projectId#', 'blocker', null, 1, now(), 1, now());
			INSERT INTO `projectticketseverities` (`severityId`, `projectId`, `severityName`, `severityDescription`, `createUserId`, `createDate`, `modifiedUserId`, `modifiedDate`) VALUES ('0', '#projectId#', 'critical', null, 1, now(), 1, now());
			INSERT INTO `projectticketseverities` (`severityId`, `projectId`, `severityName`, `severityDescription`, `createUserId`, `createDate`, `modifiedUserId`, `modifiedDate`) VALUES ('0', '#projectId#', 'major', null, 1, now(), 1, now());
			INSERT INTO `projectticketseverities` (`severityId`, `projectId`, `severityName`, `severityDescription`, `createUserId`, `createDate`, `modifiedUserId`, `modifiedDate`) VALUES ('0', '#projectId#', 'normal', null, 1, now(), 1, now());
			INSERT INTO `projectticketseverities` (`severityId`, `projectId`, `severityName`, `severityDescription`, `createUserId`, `createDate`, `modifiedUserId`, `modifiedDate`) VALUES ('0', '#projectId#', 'minor', null, 1, now(), 1, now());
			INSERT INTO `projectticketseverities` (`severityId`, `projectId`, `severityName`, `severityDescription`, `createUserId`, `createDate`, `modifiedUserId`, `modifiedDate`) VALUES ('0', '#projectId#', 'trivial', null, 1, now(), 1, now());
			INSERT INTO `projectticketstatuses` (`statusId`, `projectId`, `statusName`, `statusDescription`, `createUserId`, `createDate`, `modifiedUserId`, `modifiedDate`) VALUES ('0', '#projectId#', 'new', null, 1, now(), 1, now());
			INSERT INTO `projectticketstatuses` (`statusId`, `projectId`, `statusName`, `statusDescription`, `createUserId`, `createDate`, `modifiedUserId`, `modifiedDate`) VALUES ('0', '#projectId#', 'assigned', null, 1, now(), 1, now());
			INSERT INTO `projectticketstatuses` (`statusId`, `projectId`, `statusName`, `statusDescription`, `createUserId`, `createDate`, `modifiedUserId`, `modifiedDate`) VALUES ('0', '#projectId#', 'opened', null, 1, now(), 1, now());
			INSERT INTO `projectticketstatuses` (`statusId`, `projectId`, `statusName`, `statusDescription`, `createUserId`, `createDate`, `modifiedUserId`, `modifiedDate`) VALUES ('0', '#projectId#', 'reopened', null, 1, now(), 1, now());
			INSERT INTO `projectticketstatuses` (`statusId`, `projectId`, `statusName`, `statusDescription`, `createUserId`, `createDate`, `modifiedUserId`, `modifiedDate`) VALUES ('0', '#projectId#', 'closed', null, 1, now(), 1, now());
			INSERT INTO `projecttickettypes` (`typeId`, `projectId`, `typeName`, `typeDescription`, `createUserId`, `createDate`, `modifiedUserId`, `modifiedDate`) VALUES ('0', '#projectId#', 'defect', null, 1, now(), 1, now());
			INSERT INTO `projecttickettypes` (`typeId`, `projectId`, `typeName`, `typeDescription`, `createUserId`, `createDate`, `modifiedUserId`, `modifiedDate`) VALUES ('0', '#projectId#', 'enhancement', null, 1, now(), 1, now());
			INSERT INTO `projecttickettypes` (`typeId`, `projectId`, `typeName`, `typeDescription`, `createUserId`, `createDate`, `modifiedUserId`, `modifiedDate`) VALUES ('0', '#projectId#', 'task', null, 1, now(), 1, now());
			INSERT INTO `projectversions` (`versionId`, `projectId`, `versionName`, `versionDescription`, `versionTime`, `createUserId`, `createDate`, `modifiedUserId`, `modifiedDate`) VALUES ('0', '#projectId#', '1.0', null, null, 1, now(), 1, now());
			INSERT INTO `projectversions` (`versionId`, `projectId`, `versionName`, `versionDescription`, `versionTime`, `createUserId`, `createDate`, `modifiedUserId`, `modifiedDate`) VALUES ('0', '#projectId#', '2.0', null, null, 1, now(), 1, now());
			</cfoutput>
		</cfsavecontent>
		<cfloop list="#defaultsSQL#" delimiters=";" index="sqlQry">
				<br /><cfdump var="#getReactorSQLParser().runQuery(sqlQry)#">
		</cfloop>
		
		<cfabort>
	</cffunction>

	<cffunction name="verifyAuthentication" access="public" returntype="any" hint="verify Authentication">
	  <cfargument name="authenticate" type="any">
			<cfset var reqData = GetHttpRequestData() />
			<cfset var authenService = getAuthenticationService() />
			<cfset var credentials = structNew() />
			<cfif IsStruct( reqData ) AND StructKeyExists( reqData, "Headers" ) AND IsStruct( reqData.Headers )
						AND StructKeyExists( reqData.Headers , "Authorization") AND REFindNoCase("Basic [A-Za-z0-9+/=]+", reqData.Headers.Authorization)>
			    <cfset userpass = ToString( ToBinary(ListLast( reqData.Headers.Authorization , " " ) ) )/>
			    <cfset username = ListFirst( userpass, ":" ) />
			    <cfset password = ListLast( userpass, ":" ) />
					<cfset credentials["username"] = username>
					<cfset credentials["password"] = hash(password,"md5")>
					<cfset authenService.setCredentials(credentials)>
					<cfset authenService.authenticate()>
			</cfif>
			<cfif NOT authenService.isAuthenticated() >
			    <cfheader statuscode="401" statustext="Access Denied" /> 
				    <cfheader name="WWW-Authenticate" 
			        value="Basic realm=""MyApplication""" />
							<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
							<html><head>
							<title>401 Authorization Required</title>
							</head><body>
							<h1>Authorization Required</h1>
							<p>This server could not verify that you
							are authorized to access the document
							requested.  Either you supplied the wrong
							credentials (e.g., bad password), or your
							browser doesn't understand how to supply
							the credentials required.</p>
							</body></html>
			    <cfabort/>
			</cfif>
	</cffunction>

	<cffunction name="getCurrentUserId" access="public" returntype="any" hint="returns current user ID">
		<cfset var creds = getAuthenticationService().getCredentials() />
		<cfset var userId = creds["userID"] />
		<cfreturn userId />		
	</cffunction>


	<cffunction name="getAPIVersion" access="public" returntype="any" hint="gets project">
	  <cfset var version = arrayNew(1)>
	  <cfset var rpcCall = "">
	  <cfset version[1] = "$int1">
	  <cfset version[2] = "$int1">
    <cfreturn version>
	</cffunction>
	
	<cffunction name="getProjectNames" access="public" returntype="any" hint="gets project">
		<cfargument name="searchParams">
		<cfscript>
			var query = getProjectService().getProjectsQuery();
	 	  projectNames = listToArray(valueList(query.projectName));
	 	  return projectNames;
		</cfscript>
	</cffunction>

	<cffunction name="getProjectComponentNames" access="public" returntype="any" hint="gets project">
		<cfargument name="projectId">
		<cfargument name="params">
		<cfscript>
			var pram = structNew();			
			var query = "";
	 	  var names = "";
	 	  pram["projectId"] = arguments.projectId;
			query = getProjectService().getProjectComponentsQuery(pram);
	 	  names = listToArray(valueList(query.componentName));
	 	  return names;
		</cfscript>
	</cffunction>

	<cffunction name="getProjectComponent" access="public" returntype="any" hint="gets project">
		<cfargument name="params">
		<cfscript>
			var componentRecord = getProjectService().getProjectComponent(params);
			var component = structNew();
		  component["name"] = componentRecord.getComponentName();
		  component["description"] = componentRecord.getComponentDescription();
		  component["owner"] = "$string" & componentRecord.getCreateUserId();
	 	  return component;
		</cfscript>
	</cffunction>

	<cffunction name="getProjectMilestoneNames" access="public" returntype="any" hint="gets project">
		<cfargument name="projectId">
		<cfargument name="params">
		<cfscript>
			var pram = structNew();			
			var query = "";
	 	  var names = "";
	 	  pram["projectId"] = arguments.projectId;
			query = getProjectService().getProjectMilestonesQuery(pram);
	 	  names = listToArray(valueList(query.milestoneName));
	 	  return names;
		</cfscript>
	</cffunction>

	<cffunction name="getProjectMilestone" access="public" returntype="any" hint="gets project">
		<cfargument name="params">
		<cfscript>
			var milestoneRecord = getProjectService().getProjectMilestone(params);
			var milestone = structNew();
			milestone["due"] = "$int" & GetEpochTime(milestoneRecord.getMilestoneDueDate());
			milestone["completed"] = "$int" & milestoneRecord.getMilestoneCompleted();
		  milestone["description"] = milestoneRecord.getMilestoneDescription();
		  milestone["name"] = milestoneRecord.getMilestoneName();
	 	  return milestone;
		</cfscript>
	</cffunction>

	<cffunction name="getProjectPriorityNames" access="public" returntype="any" hint="gets project">
		<cfargument name="params" default="#structNew()#">
		<cfscript>
			var query = getProjectService().getProjectPrioritiesQuery(params);
	 	  var names = listToArray(valueList(query.priorityName));
	 	  return names;
		</cfscript>
	</cffunction>

	<cffunction name="getProjectPriority" access="public" returntype="any" hint="gets project">
		<cfargument name="params">
		<cfscript>
			var priorityRecord = getProjectService().getProjectPriority(params);
			var priority = "$string" & priorityRecord.getPriorityId();
	 	  return priority;
		</cfscript>
	</cffunction>

	<cffunction name="getProjectVersionNames" access="public" returntype="any" hint="gets project">
		<cfargument name="params" default="#structNew()#">
		<cfscript>
			var query = getProjectService().getProjectVersionsQuery(params);
	 	  var names = listToArray(valueList(query.versionName));
	 	  var x = 0;
	 	  for (x = 1; x lte arrayLen(names); x = x + 1) {
	 	  	names[x] = "$string" & names[x]; 
	 	  }
	 	  return names;
		</cfscript>
	</cffunction>

	<cffunction name="getProjectVersion" access="public" returntype="any" hint="gets project">
		<cfargument name="params">
		<cfscript>
			var versionRecord = getProjectService().getProjectVersion(params);
			var version = structNew();
		  version["name"] = "$string" & versionRecord.getVersionName();
		  version["description"] = "$string" & versionRecord.getVersionTime();
		  version["time"] = "$int0" & GetEpochTime(versionRecord.getVersionTime());
	 	  return version;
		</cfscript>
	</cffunction>


<!---
	WIKI SERVICE FUNCTIONS 
 --->

	<cffunction name="getWikiPage" access="public" returntype="any" hint="gets project">
		<cfargument name="params">
		<cfscript>
			dumpvar(params);
		</cfscript>
	</cffunction>

<!---
	TICKET SERVICE FUNCTIONS 
 --->

	<cffunction name="getTicketResolutionNames" access="public" returntype="any" hint="gets project">
		<cfargument name="params" default="#structNew()#">
		<cfscript>
			var query = getTicketService().getTicketResolutionsQuery(params);
	 	  var names = listToArray(valueList(query.resolutionName));
	 	  return names;
		</cfscript>
	</cffunction>

	<cffunction name="getTicketResolution" access="public" returntype="any" hint="gets project">
		<cfargument name="params">
		<cfscript>
			var resolutionRecord = getTicketService().getTicketResolution(params);
		  resolution = "$string" & resolutionRecord.getResolutionId();
	 	  return resolution;
		</cfscript>
	</cffunction>

	<cffunction name="getTicketSeverityNames" access="public" returntype="any" hint="gets project">
		<cfargument name="params">
		<cfscript>
			var query = getTicketService().getTicketSeverityQuery(params);
	 	  var names = listToArray(valueList(query.severityName));
	 	  return names;
		</cfscript>
	</cffunction>

	<cffunction name="getTicketSeverity" access="public" returntype="any" hint="gets project">
		<cfargument name="params">
		<cfscript>
			var severityRecord = getTicketService().getTicketSeverity(params);
		  severity = "$string" & severityRecord.getSeverityId();
	 	  return severity;
		</cfscript>
	</cffunction>

	<cffunction name="getTicketStatusNames" access="public" returntype="any" hint="gets project">
		<cfargument name="params">
		<cfscript>
			var query = getTicketService().getTicketStatusQuery(params);
	 	  var names = listToArray(valueList(query.statusName));
	 	  return names;
		</cfscript>
	</cffunction>

	<cffunction name="getTicketStatus" access="public" returntype="any" hint="gets project">
		<cfargument name="params">
		<cfscript>
			var statusRecord = getTicketService().getTicketStatus(params);
		  status = "$string" & statusRecord.getStatusId();
	 	  return status;
		</cfscript>
	</cffunction>

	<cffunction name="getTicketTypeNames" access="public" returntype="any" hint="gets project">
		<cfargument name="params">
		<cfscript>
			var query = getTicketService().getTicketTypeQuery(params);
	 	  var names = listToArray(valueList(query.typeName));
	 	  return names;
		</cfscript>
	</cffunction>

	<cffunction name="getTicketType" access="public" returntype="any" hint="gets project">
		<cfargument name="params">
		<cfscript>
			var statusRecord = getTicketService().getTicketType(params);
		  status = "$string" & statusRecord.getTypeId();
	 	  return status;
		</cfscript>
	</cffunction>

	<cffunction name="getTicketFields" access="public" returntype="any" hint="gets project">
		<cfargument name="params">
		<cfscript>
			var ticketFields = getTicketService().getTicketFields(params);
	 	  return ticketFields;
		</cfscript>
	</cffunction>

	<cffunction name="getTicketQuery" access="public" returntype="any" hint="gets project">
		<cfargument name="projectId">
		<cfargument name="params">
		<cfscript>
			var prams = structNew();
			var param = "";
			var query = "";
	 	  var ticketIds = "";
	 	  var qrystr = arguments.params[1];
/*
TODO: figure out a good query adapter thing
~= : contains
!~= : not contains
$= : ends with
^= : begins
| : or
order=id&amp;summary~=summarystuff&amp;keywords~=key words rock&amp;status=new|assigned|reopened&amp;type=closed|trivial&amp;version=1|2&amp;milestone=milestone two&amp;component=dpages&amp;description~=descriptionstuff&amp;priority=low|lowest&amp;owner~=denny
order=id&amp;summary!~=summarystuff&amp;keywords$=key words rock&amp;status=new|assigned|reopened&amp;type=closed|trivial&amp;version=1|2&amp;milestone=milestone two&amp;component=dpages&amp;description^=descriptionstuff&amp;priority=low|lowest&amp;owner~=denny
~=
^=
$=
*/
			for(x = 1; x lte listLen(qrystr,"&"); x = x+1) {
				param = listGetAt(qrystr,x,"&");
				attribs = structNew();
				attrib = listFirst(param,"=^$!~");
				attribs["pr"][x] = param;	 
				attribs[attrib] = structNew();			 
				 attribs[attrib]["value"] = listLast(param,"=");
				 attribs[attrib]["operator"] = "=";
				 if(find('~',param)) { 
				 attribs[attrib]["operator"] = "~";
				 }
				 if(find('$',param)) { 
				 attribs[attrib]["operator"] = "$";
				 }
				 if(find('^',param)) { 
				 attribs[attrib]["operator"] = "^";
				 }
				 if(find('!',param)) { 
				 attribs[attrib]["operator"] = "!" & attribs[attrib]["operator"];
				 }
			}
			prams["projectId"] = arguments.projectId;
//			dumpvar(attribs);  REGEXP 'operator + '
			query = getTicketService().getTicketQuery(prams);
			ticketIds = listToArray(valueList(query.ticketId));
	 	  return ticketIds;
		</cfscript>
	</cffunction>

	<cffunction name="getTicket" access="public" returntype="any" hint="gets project">
		<cfargument name="params">
		<cfscript>
		  var ticket = arrayNew(1);
		  var attribs = structNew();
		  var loc = structNew();
		  var rpcCall = "";
		  var addhrs = 0;
//			var ticketRecord = getTicketService().getTicket(params);
			var ticketRecord = getTicketService().getTicketView(params);
		</cfscript>
<!--- 
CREATE OR REPLACE VIEW  `projects`.`vw_projecttickets` AS 
select `t`.`ticketId` AS `ticketID`,`t`.`projectId` AS `projectId`,
`t`.`ticketSummary` AS `ticketSummary`,`t`.`ticketdescription` AS `ticketdescription`,
`t`.`tickettype` AS `tickettype`,`t`.`ticketcomponent` AS `ticketcomponent`,
`t`.`ticketmilestone` AS `ticketmilestone`,`t`.`ticketseverity` AS `ticketseverity`,
`t`.`ticketresolution` AS `ticketresolution`,`t`.`ticketpriority` AS `ticketpriority`,
`t`.`ticketPriorityOrder` AS `ticketpriorityorder`,`t`.`ticketstatus` AS `ticketstatus`,
`t`.`ticketcc` AS `ticketcc`,`t`.`ticketversion` AS `ticketversion`,
`t`.`ticketcreated` AS `ticketcreated`,`t`.`ticketmodified` AS `ticketmodified`,
`t`.`ticketKeywords` AS `ticketkeywords`,`t`.`modifiedUserId` AS `modifiedUserId`,
`t`.`createUserId` AS `createUserId`,`t`.`estimatedHours` AS `estimatedhours`,
`t`.`totalHours` AS `totalhours`,`o`.`username` AS `ticketowner`,
`r`.`username` AS `ticketreporter` 
from ((`projecttickets` `t` 
	left join `users` `o` on((`t`.`ticketowner` = `o`.`userID`))) 
	left join `users` `r` on((`t`.`ticketowner` = `r`.`userID`)))

CREATE OR REPLACE VIEW vw_projecttickethours AS 
select t.*,  h.ticketHoursId, h.startdatetime,h.enddatetime,h.numhours,h.createUserId as houruserid 
from vw_projecttickets t LEFT JOIN projecttickethours h ON t.ticketId = h.ticketId
 --->
	  <cfset ticket[1] = "$int" & ticketRecord.getTicketId()><!--- ticketid --->
	  <!--- something up with the timezone? (UTC -7)  --->
	  <cfset ticket[2] = "$int" & GetEpochTime(ticketRecord.getTicketCreated())><!--- created--->
	  <cfset ticket[3] = "$int" & GetEpochTime(ticketRecord.getTicketModified())><!--- created--->
	  <cfset attribs["status"] = "$string" & ticketRecord.getTicketStatus() />
	  <cfset attribs["description"] = "$string" & ticketRecord.getTicketDescription() />
	  <cfset attribs["reporter"] = "$string" & ticketRecord.getTicketReporter()/>
	  <cfset attribs["cc"] = "$string" & ticketRecord.getTicketCC()>
	  <cfset attribs["resolution"] = "$string" & ticketRecord.getTicketResolution()>
	  <cfset attribs["component"] = "$string" & ticketRecord.getTicketComponent()>
	  <cfset attribs["summary"] = "$string" & ticketRecord.getTicketSummary()>
	  <cfset attribs["priority"] = "$string" & ticketRecord.getTicketPriority()>
	  <cfset attribs["keywords"] = "$string" & ticketRecord.getTicketKeywords()>
	  <cfset attribs["version"] = "$string" & ticketRecord.getTicketVersion()>
	  <cfset attribs["milestone"] = "$string" & ticketRecord.getTicketMilestone()>
	  <cfset attribs["owner"] = "$string" & ticketRecord.getTicketOwner() />
	  <cfset attribs["type"] = "$string" & ticketRecord.getTicketType()>
	  <cfset attribs["severity"] = "$string" & ticketRecord.getTicketSeverity()>
	  <cfset attribs["ticketpriorityorder"] = "$int" & val(ticketRecord.getTicketPriorityOrder())>
	  <cfset attribs["estimatedhours"] = "$double" & val(ticketRecord.getEstimatedHours())>
	  <cfset attribs["totalhours"] = "$double" & val(ticketRecord.gettotalhours())>
	  <cfset attribs["blocking"] = "$string" & ticketRecord.getTicketBlocking() />
	  <cfset attribs["blockedby"] = "$string" & ticketRecord.getTicketBlockedBy() />
	  <cfif isDate(ticketRecord.getTicketModified())>
		  <cfset addhrs = decimalFormat(dateDiff("n",ticketRecord.getTicketModified(),now())/60) />
		</cfif>
	  <cfif val(addhrs) lt 0><cfset addhrs = 0 /></cfif>
	  <cfset attribs["addhours"] = "$double" & val(replace(addhrs,",","","all")) />
	  <cfset ahdt_default = dateformat(now(),"mm/dd/yyyy") & " " & timeformat(now(),"short")>
	  <cfset attribs["hoursdatetime"] = "$string" & ahdt_default />
	  <cfset ticket[4] = attribs><!--- created--->
    <cfreturn ticket>

	</cffunction>

	<cffunction name="getTicketComments" access="public" returntype="any" hint="gets project">
		<cfargument name="params">
		<cfscript>
			var ticketChangeLog = arrayNew(2);
			var prams = structNew();
			var query = "";
			prams["ticketId"] = arguments.params[1];
//			prams["modifiedDate"] = arguments.params[2];
			query = getTicketService().getTicketCommentsQuery(prams);
	 	  for(x = 1; x lte query.recordcount; x = x + 1) {
	 	   ticketChangeLog[x][1] = "$int" & GetEpochTime(query["createDate"][x]);
	 	   ticketChangeLog[x][2] = "$string" & query["createUserId"][x];
	 	   ticketChangeLog[x][3] = "$string" & "comment";
	 	   ticketChangeLog[x][4] = "$string" & "1"; // oldvalue?
	 	   ticketChangeLog[x][5] = "$string" & query["commentText"][x]; // newvalue?
	 	   ticketChangeLog[x][6] = "$string" & "1"; // permanent?
	 	  }
	 	  return ticketChangeLog;
		</cfscript>
	</cffunction>

	<cffunction name="getTicketAttachments" access="public" returntype="any" hint="gets project">
		<cfargument name="params">
		<cfscript>
			var ticketAttachments = arrayNew(2);
			var prams = structNew();
			var query = "";
			prams["ticketId"] = arguments.params["ticketId"];
//			prams["modifiedDate"] = arguments.params[2];
			query = getTicketService().getTicketAttachmentsQuery(prams);
	 	  for(x = 1; x lte query.recordcount; x = x + 1) {
	 	   ticketAttachments[x][1] = "$string" & query["attachmentFileName"][x];
	 	   ticketAttachments[x][2] = "$string" & query["attachmentDescription"][x];
	 	   ticketAttachments[x][3] = "$int" & query["attachmentFileSize"][x];
	 	   ticketAttachments[x][4] = "$int" & GetEpochTime(query["createDate"][x]);
	 	   ticketAttachments[x][5] = "$string" & query["createUserId"][x];
	 	  }
	 	  return ticketAttachments;
		</cfscript>
	</cffunction>

	<cffunction name="getTicketAvailableActions" access="public" returntype="any" hint="gets project">
		<cfargument name="params">
		<cfscript>
			var query = getTicketService().getTicketAvailableActionsQuery(params);
	 	  var names = listToArray(valueList(query.actionName));
	 	  return names;
		</cfscript>
	</cffunction>

	<cffunction name="updateTicket" access="public" returntype="any" hint="">
		<cfargument name="projectId">
		<cfargument name="params">
		<cfscript>
			var ticketParams = structNew();
			var ticket = "";
			var retTicket = structNew();
			ticketParams.ticketId = params[1];
			ticketParams.userId = getCurrentUserID();
			ticketParams.projectId = arguments.projectId;
			ticketParams.ticketAttributes = params[3];
			ticketParams.ticketAttributes["comment"] = params[2];
			ticketParams.ticketNotifys = params[4];
			ticket = getTicketService().persistTicket(ticketParams);
			retTicket.ticketId=ticket.getTicketId();
	 	  return getTicket(retTicket);
		</cfscript>
	</cffunction>

	<cffunction name="createTicket" access="public" returntype="any" hint="">
		<cfargument name="projectId">
		<cfargument name="params">
		<cfscript>
			var ticketParams = structNew();
			var ticket = "";
			var retTicket = structNew();
			ticketParams.ticketId = 0;
			ticketParams.userId = getCurrentUserID();
			ticketParams.ticketAttributes = params[3];
			ticketParams.ticketAttributes["summary"] = params[1];
			ticketParams.ticketAttributes["description"] = params[2];
			ticketParams["projectId"] = arguments.projectId;
			ticketParams.ticketNotifys = params[4];			
			ticket = getTicketService().persistTicket(ticketParams);
	 	  return "$int" & ticket.getTicketId();
		</cfscript>
	</cffunction>

	<cffunction name="getRecentChanges" access="public" returntype="any" hint="">
		<cfargument name="projectId">
		<cfargument name="params">
		<cfscript>
			var changedTickets = getTicketService().getRecentChangesQuery(projectId,params);
	 	  var changedTicketIds = listToArray(valueList(changedTickets.ticketId));
	 	  var x = 0;
	 	  for (x = 1; x lte arrayLen(changedTicketIds); x = x + 1) {
	 	  	changedTicketIds[x] = "$int" & changedTicketIds[x]; 
	 	  }
	 	  return changedTicketIds;
		</cfscript>
	</cffunction>

	<cffunction name="saveAttachment" access="public" returntype="any" hint="">
		<cfargument name="params">
		<cfscript>
			var attachmentParams = structNew();
			var attachment = "";
			var attachmentRecord = "";
			attachmentParams["ticketId"] = params[1];
			attachmentParams["AttachmentFileName"] = params[2];
			attachmentParams["AttachmentDescription"] =params[3];
			attachmentParams["AttachmentFileData"]=params[4];
			attachmentParams["CreateUserId"]=3;
			attachmentRecord = getTicketService().saveAttachment(attachmentParams);

		  attachmentName = "$string" & attachmentRecord.getAttachmentFileName();
	 	  return attachmentName;
		</cfscript>
	</cffunction>

	<cffunction name="getTicketAttachment" access="public" returntype="any" hint="used for xml">
		<cfargument name="params">
		<cfscript>
			var attachment = structNew();
			var attachmentRecord = "";
			attachment["ticketId"] = params[1];
			attachment["AttachmentFileName"] = params[2];
			attachmentRecord = getTicketService().getAttachment(attachment);
		  attachmentFileData = "$base64" & attachmentRecord.getAttachmentFileData();
	 	  return attachmentFileData;
		</cfscript>
	</cffunction>

	<cffunction name="viewAttachment" access="public" returntype="any" hint="">
		<cfargument name="params">
	  <cfset getTicketService().viewAttachment(params)>
	</cffunction>

	<cffunction name="runMethod" access="public" returntype="any" hint="">
	  <cfargument name="projectId" required="true" type="numeric" />
	  <cfargument name="method" default="" />
	  <cfargument name="params" default="" />
	  <cfset var response = structNew()>
	  <cfset var results = arrayNew(1)>
	  <cfset var rpcResult = "">
		<cfset var rpcMethodMap = getG11nService().getRB("xmlrpc_trac").getResourceBundleData() />
		<cfset var funkParams = structNew() />
	  <cfset var subArray = arrayNew(1) />
	  <cfset var prams = structNew() />
	  <cfset var responsetype = "response">
	  <cfset verifyAuthentication() />
	  <cfif isArray(arguments.params) and arrayLen(arguments.params) eq 1>
	    <!--- convert the array into a struct, and get the key name --->
		  <cfset methodFieldname = method & ".fieldname" />
		  <cfif structKeyExists(rpcMethodMap,methodFieldName)>
			  <cfset prams[rpcMethodMap[methodFieldname]] = params[1] />
			  <cfset arguments.params = prams />
			</cfif>
		<cfelseif isArray(arguments.params) and arrayLen(arguments.params) eq 0>
			  <cfset arguments.params = prams />		
		</cfif>
		<cfif isStruct(arguments.params) >
		  <cfset arguments.params["projectId"] =  arguments.projectId />
		</cfif>
		<cfset funkParams["projectId"] = arguments.projectId />
		<cfset funkParams["params"] = arguments.params />
		<cfif structKeyExists(rpcMethodMap,method)>
			<cftry>
			  <cfinvoke method="#rpcMethodMap[method]#" argumentcollection="#funkParams#" returnvariable="rpcResult">
			<cfcatch>
	  		<cfset responsetype = "responsefault" />
				<cfset rpcResult = arrayNew(1)>
				<cfset rpcResult[1] = 3>
				<cfset rpcResult[2] = cfcatch.Message & ":" & cfcatch.Detail>
				<cfsavecontent variable="moreinfo">
					<cfloop from="1" to="#arrayLen(cfcatch.tagContext)#" index="x">
						<cfset rpcResult[2] = rpcResult[2] & "Method: " & method & " --- " & cfcatch.Detail & ": LINE " & cfcatch.TagContext[x].line & " TEMPLATE: " & cfcatch.TagContext[x].template>
					</cfloop>
				</cfsavecontent>
			</cfcatch>
			</cftry>
		<cfelse>
 		  <cfthrow type="TracRpcAdapter.noMethod" message="no mehtod: #method#" />
 		 	<!--- <cfset rpcResult = getAPIVersion() /> --->
		</cfif>
		<cfif responsetype eq "responsefault">
			<cfset results = rpcResult />
		<cfelse>
			<cfset results[1] = rpcResult />
		</cfif>
		<cfset response["results"] = results />
		<cfset response["responsetype"] = responsetype />
	  <cfreturn response>
	</cffunction>

	<cffunction name="multicall" access="public" returntype="any" hint="">
		<cfargument name="projectId" required="true">
		<cfargument name="params" required="true">
		<cfset var callArray = params />
	  <cfset var myArray = arrayNew(1) />
	  <cfset var subArray = arrayNew(1) />
	  <cfset var response = structNew() />
	  <cfset var responseresults = structNew() />
	  <cfset var responsetype = "response">
	  <cfif isStruct(callArray)>
		  <cfset callArray = callArray["multiCall"] />
		</cfif>
		<cfloop from="1" to="#arrayLen(callArray)#" index="x">
			<cfset responseresults = runMethod(arguments.projectId,callArray[x]["methodName"],callArray[x]["params"]) />
			<cfset myArray[x] = responseresults["results"] />
		</cfloop>
	  <cfreturn myArray>
	</cffunction>

	<cffunction name="runCalledMethod" access="public" returntype="any" hint="gets project">
		<cfargument name="project">
	  <cfset var projectID = arguments.project />
	  <cfset var rpcCall = variables._xmlrpc.XMLRPC2CFML(data=GetHttpRequestData().content) />	  
	  <cfset var method = rpcCall["method"] />
	  <cfset var params = rpcCall["params"] />
	  <cfset var response = structNew() />
	  <cfset var error = arrayNew(1) />
	  <cfif GetHttpRequestData().content eq ""><cfset method = "system.getAPIVersion" /></cfif>
	  <cfif method eq "Error">
		  <cfreturn variables._xmlrpc.CFML2XMLRPC(data=params,type="responsefault") />
		</cfif>
	  <cfset response = runMethod(projectId,method,params) />
	  <cfreturn variables._xmlrpc.CFML2XMLRPC(data=response["results"],type=response["responsetype"]) />
	</cffunction>

</cfcomponent>